#ifndef REDISCONNECTIONPOOL_H
#define REDISCONNECTIONPOOL_H

#include <mutex>
#include <list>

#include "hiredis/hiredis.h"

#include "CacheConnectionPool.h"

#define REDIS_12_HOURS 12*3600

class RedisConntion : public CacheConnection {
public:
    RedisConntion(const char* ip,int port,const char* auth = NULL);
    ~RedisConntion();

    int init();

    bool get(const char* key,std::string& value);
    bool set(const char* key,const char* value);
    bool set(const char* key,const char* value,int ex);

    const char* getLastError();

private:
    std::string m_ip;
    int m_port;
    std::string m_auth;

    redisContext* context;
    std::string errorstr;

    bool isEffective();
    bool checkReply(const redisReply *reply);
    void freeReply(const redisReply *reply);
    void setErrorInfo(const char* err,int len);
};

class RedisConnectionPool : public CacheConnectionPool {
public:
    RedisConnectionPool(const char* ip,int port,const char* auth,int init_count = 1,int max_count = 100);
    ~RedisConnectionPool();

    int init();

    CacheConnection* getCacheConnection();
    void putCacheConnection(CacheConnection* conn);
    int getConnectionCount();

private:
    int m_init_count;
    int m_max_count;
    int m_count;
    std::list<CacheConnection*> m_free_conn_list;
    std::mutex m_mutex;

    std::string m_ip;
    int m_port;
    std::string m_auth;
};

#endif // REDISCONNECTIONPOOL_H
